package com.chefu.admin.service.impl;

import com.chefu.admin.config.JwtProperties;
import com.chefu.admin.pojo.ServiceProvider;
import com.chefu.admin.pojo.mongo.ServerProLocation;
import com.chefu.admin.service.PositionService;
import com.chefu.carowner.pojo.mongo.UserLocation;
import com.chefu.common.constants.CfConstants;
import com.chefu.common.exception.CfException;
import com.chefu.common.exception.ExceptionEnum;
import com.chefu.common.utils.DistanceUtils;
import com.chefu.common.utils.auth.JwtUtils;
import com.chefu.common.utils.auth.Payload;
import com.chefu.common.utils.auth.UserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.geo.Circle;
import org.springframework.data.geo.Distance;
import org.springframework.data.geo.Metrics;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.geo.GeoJsonPoint;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import java.util.List;

@Service
public class PositionServiceImpl implements PositionService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private JwtProperties jwtProp;

    @Override
    public void saveServerProLocation(ServiceProvider serviceProvider) {
        Query query = new Query(Criteria.where("serverProId").is(serviceProvider.getSpId()));
        if (!mongoTemplate.exists(query, ServerProLocation.class)){
            ServerProLocation location = new ServerProLocation();
            location.setServerProId(serviceProvider.getSpId());
            location.setServerProName(serviceProvider.getShortName());
            location.setStar(4.5);
            location.setChain(serviceProvider.gettChain()?"驰加连锁":"");
            location.setCreateTime(System.currentTimeMillis());
            location.setLocation(new GeoJsonPoint(serviceProvider.getLatitude(),serviceProvider.getLongitude()));
            location.setAddress(serviceProvider.getAddress());
            location.setUpdateTime(System.currentTimeMillis());
            location.setLastUpdateTime(System.currentTimeMillis());
            mongoTemplate.save(location);
        }else{
            Update update = new Update();
//            update.set("star",)
//            update.set("chain")
            update.set("address",serviceProvider.getAddress());
            update.set("updateTime",System.currentTimeMillis());
            update.set("lastUpdateTime",System.currentTimeMillis());
            update.set("location",new GeoJsonPoint(serviceProvider.getLatitude(),serviceProvider.getLongitude()));
            mongoTemplate.updateFirst(query,update,UserLocation.class);
        }
    }

    @Override
    public List<ServerProLocation> getNearServerPro(HttpServletRequest request) {
        String token = request.getHeader(CfConstants.APP_TOKEN_HEADER);
        Payload<UserInfo> payload = null;

        try {
            payload = JwtUtils.getInfoFromToken(token, jwtProp.getPublicKey(), UserInfo.class);
        } catch (Exception e) {
            e.printStackTrace();
            throw new CfException(ExceptionEnum.UNAUTHORIZED);
        }
        UserInfo info = payload.getInfo();
        if (info.getUserType()!=0) throw new CfException(ExceptionEnum.UNAUTHORIZED);
        Long userId = info.getId();

        Query query = new Query(Criteria.where("userId").is(userId));
        UserLocation userLocation = mongoTemplate.findOne(query, UserLocation.class);

        Distance distanceObj = new Distance(50000 / 1000, Metrics.KILOMETERS);

        GeoJsonPoint location = userLocation.getLocation();

        Circle circle = new Circle(location, distanceObj);
        Query locationQuery = new Query(
                Criteria.where("location").withinSphere(circle)
        );
//        NearQuery nearQuery = NearQuery.near(location, Metrics.KILOMETERS).minDistance(distanceObj).query(query);

        List<ServerProLocation> serverProList = mongoTemplate.find(locationQuery,ServerProLocation.class);

        for (ServerProLocation serverProLocation : serverProList) {
            GeoJsonPoint serverProPoint = serverProLocation.getLocation();
            String distance = DistanceUtils.getDistanceOfTwoPoints(location.getX(), location.getY(), serverProPoint.getX(), serverProPoint.getY());
            serverProLocation.setDistance(distance);
        }

        return serverProList;
    }
}
